package logger.sd.server;

import java.util.ArrayList;
import java.util.List;

import logger.sd.util.Configuration;

/**
 * Leitor de Configuracoes do Servidor. 
 * 
 * @author wendell
 * 
 */
public class ServerConfiguration extends Configuration {

	private static String defaultFilename = "ConfigFile";

	private String strategy;
	private Integer threapoolSize;
	private Integer conit;
	private String logFilename;
	private String port;
	private String level;
	private Long sleeptime;
	private Long tokentime;
	private String service;
	private String nextHost;
	private String nextPort;
	private boolean first = true;

	private List<String> othersServers;

	/**
	 * Construtor com filename
	 */
	public ServerConfiguration(String filename) {
		readConfigurations(filename);
	}

	/**
	 * Construtor sem filename
	 */
	public ServerConfiguration() {
		readConfigurations(defaultFilename);
	}

	/**
	 * Retorna o tipo do servidor Monothread, multithread, threadpool
	 * 
	 * @return Estrategia do servidor (monothread, threadpool, etc)
	 */
	public String getStrategy() {
		if (this.strategy == null) {
			this.strategy = this.getConfig("server.strategy");
		}
		if (strategy.equals("default")) {
			return "threadpool";
		}
		return strategy;
	}

	/**
	 * Retorna o tamanho do pool de threads
	 * 
	 * @return Tamanho do pool de threads
	 */
	public int getThreadPoolSize() {
		String strSize = "default";
		if (this.threapoolSize == null) {
			strSize = this.getConfig("server.threadpoolsize");
		}
		if (strSize.equals("default")) {
			threapoolSize = new Integer(50);
		} else {
			threapoolSize = Integer.parseInt(strSize);
			if (threapoolSize <= 0) {
				threapoolSize = 1;
			}
		}
		return threapoolSize;
	}
	
	/**
	 * Retorna o tamanho da conit
	 * @return
	 */
	public int getConit() {
		String strConit = "default";
		if (this.conit == null) {
			strConit = this.getConfig("server.conit");
		}
		if (strConit.equals("default")) {
			this.conit = new Integer(5);
		} else {
			this.conit = Integer.parseInt(strConit);
			if (this.conit <= 0) {
				this.conit = 1;
			}
		}
		return this.conit;
	}

	/**
	 * Retorna onde sera armazenado o arquivo de log
	 * 
	 * @return Nome do arquivo de log
	 */
	public String getLogFilename() {
		if (this.logFilename == null) {
			logFilename = this.getConfig("server.logfile");
		}
		if (logFilename.equals("default")) {
			return "LogServer";
		}
		return logFilename;
	}

	/**
	 * Retorna o tipo de servico oferecido pelo servidor
	 * 
	 * @return service Servico
	 */
	public String getService() {
		if (service == null) {
			service = this.getConfig("server.service");
		}
		if (service.equals("default")) {
			return "Logging";
		}
		return service;
	}

	/**
	 * Retorna o tempo ocioso do servidor (apenas para servico de espera -
	 * entrega 02)
	 * 
	 * @return Tempo do servico de wait
	 */
	public Long getWait() {
		if (sleeptime == null) {
			String strTime = this.getConfig(this.getConfig("server.wait"));
			if (strTime.equals("default")) {
				sleeptime = new Long(5000L);
			} else {
				sleeptime = Long.parseLong(strTime);
				if (sleeptime <= 0) {
					sleeptime = 1L;
				}
			}
		}
		return sleeptime;
	}

	/**
	 * Configura o nivel de log do servidor.
	 * 
	 * @return Nivel do servidor de logger
	 */
	public String getLevel() {
		if (this.level == null) {
			level = this.getConfig("server.level");
		}
		if (level.equals("default")) {
			return "ALL";
		}
		return level;
	}

	/**
	 * Retorna a porta onde o servidor ficara em escuta
	 * 
	 * @return Porta de escuta do servidor
	 */
	public Integer getPort() {
		if (this.port == null) {
			port = getConfig("server.port");
		}
		if (port.equals("default")) {
			return 6789;
		}
		return Integer.parseInt(port);
	}

	/**
	 * Retorna o host do proximo servidor no ringo do token ring
	 * 
	 * @return Host do proximo servidor no ring do token ring
	 */
	public String getNextHostServer() {
		if (this.nextHost == null) {
			nextHost = getConfig("server.nexthost");
		}
		if (nextHost.equals("default")) {
			return "localhost";
		}
		return nextHost;
	}

	/**
	 * Retorna a porta do proximo servidor no ringo do token ring
	 * 
	 * @return Porta do proximo servidor no ring do token ring
	 */
	public Integer getNextPortServer() {
		if (this.nextPort == null) {
			nextPort = getConfig("server.nextport");
		}
		if (nextPort.equals("default")) {
			return 0;
		}
		return Integer.parseInt(nextPort);
	}

	/**
	 * @param threapoolSize
	 *            the threapoolSize to set
	 */
	public void setThreapoolSize(Integer threapoolSize) {
		this.threapoolSize = threapoolSize;
	}

	/**
	 * @param logfile
	 *            the logfile to set
	 */
	public void setLogfile(String logfile) {
		this.logFilename = logfile;
	}

	/**
	 * @param sleeptime
	 *            the sleeptime to set
	 */
	public void setSleeptime(Long sleeptime) {
		this.sleeptime = sleeptime;
	}

	/**
	 * @param nextHost
	 *            the nextHost to set
	 */
	public void setNextHost(String nextHost) {
		this.nextHost = nextHost;
	}

	/**
	 * @param nextPort
	 *            the nextPort to set
	 */
	public void setNextPort(String nextPort) {
		this.nextPort = nextPort;
	}

	/**
	 * @param strategy
	 *            the strategy to set
	 */
	public void setStrategy(String strategy) {
		this.strategy = strategy;
	}

	/**
	 * @param port
	 *            the port to set
	 */
	public void setPort(String port) {
		this.port = port;
	}

	/**
	 * @param level
	 *            the level to set
	 */
	public void setLevel(String level) {
		this.level = level;
	}

	/**
	 * @param service
	 *            the service to set
	 */
	public void setService(String service) {
		this.service = service;
	}

	public void setTokentime(Long tokentime) {
		this.tokentime = tokentime;
	}

	/**
	 * 
	 * @return O tempo que o token ficara em cada servidor
	 */
	public Long getTokentime() {
		if (tokentime == null) {
			String strTime = this.getConfig(this.getConfig("server.tokentime"));
			if (strTime.equals("default")) {
				tokentime = new Long(10000L);
			} else {
				tokentime = Long.parseLong(strTime);
				if (tokentime <= 0) {
					tokentime = 10000L;
				}
			}
		}
		return tokentime;
	}

	/**
	 * Configura o servidor para iiciar com o token
	 * @param first
	 */
	public void setFirst(boolean first) {
		this.first = first;
	}

	public boolean isFirst() {
		String strFirst = "default";
		if (!this.first) {
			strFirst = this.getConfig("server.first");
		}
		if (strFirst.equals("true")) {
			this.first = true;
		}
		return this.first;
	}

	/**
	 * Retorna quem sao os outros servidores.
	 * 
	 * @return
	 */
	public List<String> getOthersServers() {
		String linha = new String();
		if (othersServers == null) {
			othersServers = new ArrayList<String>();
			linha = this.getConfig("server.others");
			if (linha.equals("default")) {
				return othersServers;
			}
			String[] linhaDividida = linha.split(",");
			for (String s : linhaDividida) {
				othersServers.add(s);
			}
		}
		return othersServers;
	}

	/**
	 * 
	 * @param othersServers
	 */
	public void setOthersServers(List<String> othersServers) {
		this.othersServers = othersServers;
	}

	public void setConit(Integer conit) {
		this.conit = conit;
	}

	
}
